package org.kl.bf.web.basic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.kl.bf.entity.basic.Organization;
import org.kl.bf.entity.basic.Post;
import org.kl.bf.entity.easyui.EasyuiGrid;
import org.kl.bf.entity.easyui.EasyuiTreeNode;
import org.kl.bf.service.ServiceException;
import org.kl.bf.service.basic.OrganizationService;
import org.kl.bf.service.basic.PostService;
import org.kl.bf.utils.KLServlets;
import org.kl.bf.web.base.BasicController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.modules.utils.Collections3;
import org.springside.modules.web.MediaTypes;

import com.github.abel533.echarts.Option;
import com.github.abel533.echarts.code.BrushType;
import com.github.abel533.echarts.code.Magic;
import com.github.abel533.echarts.code.Tool;
import com.github.abel533.echarts.code.Trigger;
import com.github.abel533.echarts.code.X;
import com.github.abel533.echarts.code.Y;
import com.github.abel533.echarts.feature.MagicType;
import com.github.abel533.echarts.series.Force;
import com.github.abel533.echarts.series.force.Link;
import com.github.abel533.echarts.series.force.Node;
import com.github.abel533.echarts.style.ItemStyle;

@Controller
@RequestMapping(value = "basic/organization")
public class OrganizationController extends BasicController {

	@Autowired
	private OrganizationService organizationService;
	@Autowired
	private PostService postService;

	@RequiresPermissions("organization:list")
	@RequestMapping(method = RequestMethod.GET)
	public String list() {
		return "basic/OrganizationList";
	}

	/**
	 * 
	 * @param id
	 *            节点编码，不是主键的id
	 * @param model
	 * @param request
	 * @return
	 */
	@RequiresPermissions("organization:list")
	// @SuppressWarnings("unchecked")
	@RequestMapping(value = "tree", method = RequestMethod.GET, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String tree(@RequestParam(value = "id", defaultValue = "") String id, Model model, ServletRequest request) {
		List<Organization> organizationList = new ArrayList<Organization>();
		organizationList = organizationService.getAllOrganization();
		/*
		 * if (StringUtils.isBlank(id)) { List<Organization> root =
		 * organizationService.findRoot(); organizationList =
		 * organizationService.getAllOrganization(); if (root != null) {
		 * organizationList.addAll(root); //
		 * System.out.println("结果是"+root.get(0).getOrgName()); }
		 * List<Organization> rootChildren =
		 * organizationService.findByOrganizationsParentOrgIdIn(Collections3
		 * .extractToList(root, "id"));
		 * 
		 * if (rootChildren != null) { organizationList.addAll(rootChildren); }
		 * } else { organizationList = organizationService.findByOrgNo(id); }
		 * 
		 * // list排序 Collections.sort(organizationList, new
		 * Comparator<Organization>() { public int compare(Organization arg0,
		 * Organization arg1) { return
		 * arg0.getOrgNo().compareTo(arg1.getOrgNo()); } });
		 */
		List<EasyuiTreeNode> plainTree = new ArrayList<EasyuiTreeNode>();
		for (Organization organization : organizationList) {
			EasyuiTreeNode one = organizationToTreeNode(organization);
			plainTree.add(one);
		}

		String result = jsonMapper.toJson(plainTree);
		return result;
	}

	// list
	@RequestMapping(value = "dataGrid", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String dataGrid(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
			@RequestParam(value = "rows", defaultValue = PAGE_SIZE) int pageSize,
			@RequestParam(value = "sort", defaultValue = "id") String sortType,
			@RequestParam(value = "order", defaultValue = "desc") String orderType, Model model, ServletRequest request) {
		Map<String, Object> searchParams = KLServlets.getParametersStartingWith(request, SEARCH_PREFIX);
		Page<Organization> organization = organizationService.getPbs(searchParams, pageNumber, pageSize, sortType, orderType);
		EasyuiGrid grid = new EasyuiGrid();
		grid.setRows(organization.getContent());
		grid.setTotal((int) organization.getTotalElements());
		String result = jsonMapper.toJson(grid);
		return result;
	}

	private EasyuiTreeNode organizationToTreeNode(Organization organization) {
		EasyuiTreeNode one = new EasyuiTreeNode();
		one.setId(organization.getId());
		one.setText(organization.getOrgNo() + "--" + organization.getOrgName());
		one.setPid(organization.getParentOrgId());
		Map<String, Object> attributes = new HashMap<String, Object>();
		attributes.put("id", organization.getId());
		attributes.put("orgNo", organization.getOrgNo());
		attributes.put("orgName", organization.getOrgName());
		attributes.put("parentOrgId", organization.getParentOrgId());
		attributes.put("zipCode", organization.getZipCode());
		attributes.put("enable", organization.getEnable());
		attributes.put("address", organization.getAddress());
		attributes.put("description", organization.getDescription());
		attributes.put("fax", organization.getFax());
		attributes.put("phoneNumber", organization.getPhoneNumber());
		one.setAttributes(attributes);

		if (StringUtils.isNotBlank(organization.getParentOrgId()) && organizationService.childrenCount(organization.getOrgNo()) > 0) {
			one.setState("closed");
		}
		return one;
	}

	@RequiresPermissions("organization:update")
	@RequestMapping(value = "update", method = RequestMethod.POST, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String update(@Valid @ModelAttribute("organization") Organization organization, RedirectAttributes redirectAttributes) {
		try {
			if (organization != null && StringUtils.isBlank(organization.getId())) {
				organization.setOrgNo("00000");
				organization.setOrgName("新节点");
				// System.out.println("父节点为"+organization.getParentOrgId());
				// organization.setPbsNodeCode("00000");
			}
			List<Organization> organizationList = organizationService.findByOrgNo(organization.getOrgNo());
			if (Collections3.isNotEmpty(organizationList)) {
				if (organizationList.size() > 1 || !organizationList.get(0).getId().equals(organization.getId())) {
					return ajaxMsg("保存失败，PBS代码" + organization.getOrgNo() + "已经存在", false, null);
				}
			}
			if (StringUtils.isNotEmpty(organization.getParentOrgId())) {
				organizationList = organizationService.findById(organization.getParentOrgId());
				System.out.println("测试" + organizationList.get(0).getOrgName());
				if (Collections3.isEmpty(organizationList)) {
					return ajaxMsg("保存失败，" + organization.getOrgNo() + "的父节点" + organization.getParentOrgId() + "不存在，请选中节点后再新增", false,
							null);
				}
			}
			organizationService.saveOrganization(organization);
			return ajaxMsg("保存成功", true, organizationToTreeNode(organization));
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("保存失败", false, null);
		}
	}

	@RequiresPermissions("organization:delete")
	@RequestMapping(value = "delete", produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String delete(@RequestParam(value = "ids", defaultValue = "") String ids, RedirectAttributes redirectAttributes) {
		try {
			if (StringUtils.isBlank(ids)) {
				return ajaxMsg("请先勾选需要删除的节点", false, null);
			}
			String[] idArray = StringUtils.split(ids, ",");
			for (String id : idArray) {
				if (StringUtils.isNotBlank(id)) {
					List<Post> postList = postService.findByOrganizationId(id);
					for (Post p : postList) {
						postService.deletePost(p.getId());
					}
				}
			}
			int count = organizationService.batchDeleteOrganization(ids);
			return ajaxMsg("成功删除" + count + "条", true, null);
		} catch (ServiceException se) {
			return ajaxMsg(se.getMessage(), false, null);
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxMsg("删除失败", false, null);
		}
	}

	@RequestMapping(value = "getId", method = RequestMethod.POST, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String getId(@RequestParam(value = "orgName", defaultValue = "") String orgName) {
		Organization o = organizationService.findByOrgName(orgName);
		return ajaxMsg("获取成功", true, o);
	}

	/**
	 * 所有RequestMapping方法调用前的Model准备方法, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性，因此仅在update时实际执行.
	 */
	@ModelAttribute
	public void getMenu(@RequestParam(value = "id", defaultValue = "-1") String id, Model model) {
		if (!id.equals("-1")) {
			model.addAttribute("organization", organizationService.getOrganization(id));
		} else {
			model.addAttribute("organization", new Organization());
		}
	}

	// ******************************************************下面是图形类界面的实现*****************************************************
	@RequiresPermissions("organization:list")
	@RequestMapping(value = "show", method = RequestMethod.GET)
	public String show() {
		return "basic/organizationMapList";
	}

	@RequiresPermissions("organization:list")
	@RequestMapping(value = "showMap", method = RequestMethod.GET, produces = MediaTypes.JAVASCRIPT_UTF_8)
	@ResponseBody
	public String showMap() {
		ItemStyle itemStyle = new ItemStyle();
		itemStyle.normal().label().show(true).textStyle().color("#333");
		itemStyle.normal().nodeStyle().brushType(BrushType.both).borderColor("rgba(255,215,0,0.6)").borderWidth(1);
		Option option = new Option();
		option.title().text("组织结构").x(X.center).y(Y.bottom);
		option.tooltip().trigger(Trigger.item).formatter("{a} : {b}");
		option.toolbox().show(true).feature(Tool.restore, new MagicType(Magic.force, Magic.chord), Tool.saveAsImage);
		option.legend().x(X.left).data("根节点", "层次结构", "职位职务");
		Force f = new Force();
		List<Node> nodes = getNodes();
		List<Link> links = getLinks();
		f.name("组织结构").categories("根节点", "层次结构", "职位职务").minRadius(4).maxRadius(10).coolDown(0.995).steps(10).nodes(nodes).links(links)
				.itemStyle(itemStyle);
		option.series(f);
		return ajaxMsg("获取成功", true, option);
	}

	private List<Node> getNodes() {
		List<Node> nodes = new ArrayList<>();
		List<Organization> orgList = organizationService.getAllOrganization();
		for (int i = 0; i < orgList.size(); i++) {
			Node n = new Node();
			int j = 0, k = 2;
			Organization o = orgList.get(i);
			n.setName(o.getOrgName());
			while (!StringUtils.isBlank(o.getParentOrgId())) {
				o = organizationService.getOrganization(o.getParentOrgId());
				j = 1;
				if (k != 0) {
					k -= 1;
				}
			}
			n.setCategory(j);
			n.setValue(k);
			nodes.add(n);
		}
		List<Post> postList = postService.getAllPost();
		for (int i = 0; i < postList.size(); i++) {
			Node n = new Node();
			int j = 2, k = 0;
			Post p = postList.get(i);
			n.setName(p.getPostName());
			while (!StringUtils.isBlank(p.getHigherPostId())) {
				p = postService.getPost(p.getHigherPostId());
			}
			n.setCategory(j);
			n.setValue(k);
			nodes.add(n);
		}
		return nodes;
	}

	private List<Link> getLinks() {
		List<Link> links = new ArrayList<>();
		List<Organization> orgList = organizationService.getAllOrganization();
		for (int i = 0; i < orgList.size(); i++) {
			Link l = new Link();
			Organization o = orgList.get(i);
			if (StringUtils.isNotBlank(o.getParentOrgId())) {
				Organization o1 = organizationService.getOrganization(o.getParentOrgId());
				l.source(o.getOrgName());
				l.target(o1.getOrgName());
				l.weight(1);
				links.add(l);
			}
		}
		List<Post> postList = postService.getAllPost();
		for (int i = 0; i < postList.size(); i++) {
			Link l = new Link();
			Post p = postList.get(i);
			if (StringUtils.isBlank(p.getHigherPostId())) {
				l.source(p.getPostName());
				l.target(p.getOrganization().getOrgName());
				l.weight(1);
				links.add(l);
			} else {
				while (!StringUtils.isBlank(p.getHigherPostId())) {
					l.source(p.getPostName());
					p = postService.getPost(p.getHigherPostId());
					l.target(p.getPostName());
					l.weight(1);
					links.add(l);
				}
			}
		}
		return links;
	}
}
